import { VirtualDOM } from '@/types/VirtualDOM'

export function isEmpty(obj: Record<string & symbol, unknown>) {
  return !!Reflect.ownKeys(obj).length
}

export class MyElement {
  constructor(
    public tagName = 'div',
    public props: Record<string, unknown> = {},
    public children: Array<MyElement | string | number> = []
  ) {
    // this._render(app)
  }

  _render() {
    const el = document.createElement(this.tagName)
    for (const key in this.props) {
      if (Object.prototype.hasOwnProperty.call(this.props, key)) {
        if (key === 'className') {
          el.setAttribute('class', this.props[key] as string)
        } else {
          el.setAttribute(key, this.props[key] as string)
        }
      }
    }
    if (Array.isArray(this.children)) {
      this.children?.forEach(v => {
        const childEl =
          v instanceof MyElement
            ? v._render()
            : document.createTextNode(v as string)
        el.appendChild(childEl)
      })
    } else {
      el.appendChild(document.createTextNode(this.children as string))
    }

    return el
  }

  [Symbol.iterator]() {
    return Object.values(this)[Symbol.iterator]()
  }
}

export function createElement(eleDom: VirtualDOM) {
  if (!isEmpty(eleDom)) return ''
  const { tagName, props = {}, children } = eleDom

  const arr: Array<MyElement | string> = []
  if (Array.isArray(children)) {
    children?.forEach(v => {
      arr.push(createElement(v))
    })
  } else {
    arr.push(children as string)
  }
  return new MyElement(tagName, props, arr.length ? arr : [''])
}

export function el(
  tagName?: string,
  props?: Record<string, unknown>,
  children?: (string | number | MyElement)[]
) {
  return new MyElement(tagName, props, children)
}

export function rgbaToHex(
  red: number,
  green: number,
  blue: number,
  alpha: number = 1
) {
  const r = red.toString(16).padStart(2, '0')
  const g = green.toString(16).padStart(2, '0')
  const b = blue.toString(16).padStart(2, '0')
  const a = Math.fround(alpha * 255)
    .toString(16)
    .padStart(2, '0')
  return `#${r}${g}${b}${a}`
}
